tok :: Eq a => [a] -> [a] -> [[a]]
tok _ [] = []
tok delims input@(x:xs)
    |x `elem` delims = tok delims xs
    |otherwise       = token : tok delims rest
  where
    isDelimiter = (`elem` delims)
    token       = takeWhile (not . isDelimiter) input
    rest        = dropWhile isDelimiter $ dropWhile (not . isDelimiter) input


parseLine :: String -> [Integer]
parseLine = map read . tok " " 

generateNext :: [Integer] -> [Integer]
generateNext lst = zipWith (-) (tail lst) (init lst)

generateLsts :: [Integer] -> [[Integer]]
generateLsts lst
    | all (== 0) lst = [lst]
    | otherwise      = lst : (generateLsts . generateNext $ lst)

getHistory :: [[Integer]] -> Integer
getHistory = sum . map last

getHistory' :: [[Integer]] -> Integer
getHistory' = foldr (\x acc -> x - acc) 0 . map head

main = do
    contents <- readFile "input.txt"

    let digits = map parseLine $ lines contents

    let digitMats = map generateLsts digits

    print $ sum . map getHistory $ digitMats

    print $ sum . map getHistory' $ digitMats